package com.yjzx.util.service.aop.ref.method;

import com.yjzx.util.common.util.StringUtils;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author yjzx
 * @date 2024/8/7
 * @description 指定方法切面
 */
public class UnmodifiableMethodInterceptor implements MethodInterceptor {
    private final Object o;
    List<String> fieldNames;
    List<RefExcludeMethod> includeMethods;
    List<RefExcludeMethod> excludeMethods;

    public UnmodifiableMethodInterceptor(Object o, RefUnmodifiableObject unmodifiableObject) {
        this.o = o;
        this.fieldNames = Arrays.asList(unmodifiableObject.excludeFields());
        this.excludeMethods = Arrays.asList(unmodifiableObject.excludeMethods());
        this.includeMethods = Arrays.asList(unmodifiableObject.includeMethods());
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        for (RefExcludeMethod includeMethod : includeMethods) {
            if (extracted(method, includeMethod)) {
                return methodProxy.invoke(this.o, objects);
            }
        }
        for (RefExcludeMethod includeMethod : excludeMethods) {
            if (extracted(method, includeMethod)) {
                throw new UnsupportedOperationException("当前对象此方法不允许访问");
            }
        }
        if (!fieldNames.contains(StringUtils.lowerFirst(method.getName().substring(3)))&&method.getName().startsWith("set")){
            throw new UnsupportedOperationException("当前对象数据不允许修改");
        }

        return methodProxy.invoke(this.o, objects);
    }

    private boolean extracted(Method method, RefExcludeMethod includeMethod)  {
        return includeMethod.methodName().equals(method.getName()) && Arrays.equals(includeMethod.ParameterTypes(), method.getParameterTypes());
    }
}
